"""
第三方去水印接口封装模块
用于调用外部API进行视频去水印处理，支持降级到本地逻辑
"""

import requests
import json
import logging
from typing import Optional, Dict, Any, Tuple
from dataclasses import dataclass
from enum import Enum
import time
from urllib.parse import urlparse

logger = logging.getLogger("watermark_remover")


class WatermarkResultStatus(Enum):
    """去水印结果状态"""
    SUCCESS = "success"
    FAILED = "failed"
    TIMEOUT = "timeout"
    INVALID_URL = "invalid_url"
    API_ERROR = "api_error"
    NETWORK_ERROR = "network_error"


@dataclass
class WatermarkResult:
    """去水印结果数据结构"""
    success: bool
    status: WatermarkResultStatus
    clean_video_url: Optional[str] = None
    original_video_info: Optional[Dict[str, Any]] = None
    error_message: Optional[str] = None
    processing_time: float = 0.0


class ThirdPartyWatermarkRemover:
    """第三方去水印接口封装类"""
    
    def __init__(self, api_base_url: str = "https://mihoyonb.com", timeout: int = 30):
        """
        初始化第三方去水印接口
        
        Args:
            api_base_url: API基础URL
            timeout: 请求超时时间（秒）
        """
        self.api_base_url = api_base_url.rstrip('/')
        self.timeout = timeout
        self.session = requests.Session()
        
        # 设置默认请求头
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
            'Accept': 'application/json',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
            'Accept-Encoding': 'gzip, deflate, br, zstd',
            'DNT': '1',
            'Sec-Ch-Ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
            'Sec-Ch-Ua-Mobile': '?0',
            'Sec-Ch-Ua-Platform': '"Windows"',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin'
        })
    
    def analyze_video(self, video_url: str, format_type: str = "json") -> Optional[Dict[str, Any]]:
        """
        调用第三方API分析视频
        
        Args:
            video_url: 视频URL或分享文本
            format_type: 返回格式，默认json
            
        Returns:
            API响应数据，失败返回None
        """
        try:
            # 验证URL格式
            if not self._validate_video_url(video_url):
                logger.warning(f"无效的视频URL: {video_url}")
                return None
            
            # 构建请求数据
            request_data = {
                "url": video_url,
                "format": format_type
            }
            
            # 构建完整API URL
            api_endpoint = f"{self.api_base_url}/api/video-analyze"
            
            logger.info(f"调用第三方API分析视频: {api_endpoint}")
            logger.debug(f"请求数据: {request_data}")
            start_time = time.time()
            
            # 发送请求，添加适当的请求头
            supports_br = False
            _brotli = None
            try:
                import brotlicffi as _brotli
                supports_br = True
            except Exception:
                try:
                    import brotli as _brotli
                    supports_br = True
                except Exception:
                    _brotli = None
                    supports_br = False

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Accept': 'application/json, text/plain, */*',
                'Accept-Encoding': 'gzip, deflate' + (', br' if supports_br else ''),
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                'Content-Type': 'application/json;charset=UTF-8',
                'Origin': 'https://mihoyonb.com',
                'Referer': 'https://mihoyonb.com/'
            }
            
            response = self.session.post(
                api_endpoint,
                json=request_data,
                headers=headers,
                timeout=self.timeout
            )
            
            processing_time = time.time() - start_time
            logger.info(f"API响应时间: {processing_time:.2f}秒")
            
            # 检查响应状态
            if response.status_code != 200:
                logger.error(f"API返回非200状态码: {response.status_code}")
                return None
            
            try:
                response_text = response.text
                logger.info(f"API原始响应内容: {response_text[:500]}...")
                logger.info(f"API响应状态码: {response.status_code}")
                logger.info(f"API响应头: {dict(response.headers)}")

                encoding = str(response.headers.get('Content-Encoding', '')).lower()
                if 'br' in encoding:
                    if _brotli:
                        decoded = _brotli.decompress(response.content)
                        response_data = json.loads(decoded.decode('utf-8'))
                    else:
                        headers_no_br = dict(headers)
                        headers_no_br['Accept-Encoding'] = 'gzip, deflate'
                        response2 = self.session.post(
                            api_endpoint,
                            json=request_data,
                            headers=headers_no_br,
                            timeout=self.timeout
                        )
                        if response2.status_code != 200:
                            logger.error(f"API返回非200状态码: {response2.status_code}")
                            return None
                        response_data = response2.json()
                else:
                    response_data = response.json()

                if response_data.get("code") != 200:
                    logger.error(f"API业务错误 - code: {response_data.get('code')}, message: {response_data.get('message')}")
                    return None

                return response_data

            except json.JSONDecodeError as e:
                logger.error(f"解析API响应JSON失败: {e}")
                logger.error(f"响应内容类型: {type(response.text)}")
                logger.error(f"响应内容前1000字符: {response.text[:1000]}")
                return None
                
        except requests.exceptions.Timeout:
            logger.error(f"API请求超时 (timeout={self.timeout}s)")
            return None
        except requests.exceptions.ConnectionError as e:
            logger.error(f"API连接错误: {e}")
            return None
        except requests.exceptions.RequestException as e:
            logger.error(f"API请求异常: {e}")
            return None
        except Exception as e:
            logger.error(f"调用第三方API时发生未知错误: {e}", exc_info=True)
            return None
    
    def remove_watermark(self, video_url: str) -> WatermarkResult:
        """
        执行去水印操作
        
        Args:
            video_url: 视频URL或分享文本
            
        Returns:
            去水印结果
        """
        start_time = time.time()
        
        try:
            # 调用第三方API分析视频
            api_response = self.analyze_video(video_url)
            
            if not api_response:
                processing_time = time.time() - start_time
                return WatermarkResult(
                    success=False,
                    status=WatermarkResultStatus.API_ERROR,
                    error_message="第三方API调用失败或无响应",
                    processing_time=processing_time
                )
            
            # 提取数据
            data = api_response.get("data", {})
            
            # 检查是否有视频URL - 优先使用final_url，如果没有则使用video字段
            clean_video_url = data.get("final_url") or data.get("video")
            
            # 验证URL的有效性
            if not clean_video_url or not self._validate_video_url(clean_video_url):
                processing_time = time.time() - start_time
                logger.warning(f"API返回的URL无效或为空: {clean_video_url}")
                return WatermarkResult(
                    success=False,
                    status=WatermarkResultStatus.FAILED,
                    error_message="API返回的视频URL无效或可能仍包含水印",
                    original_video_info=data,
                    processing_time=processing_time
                )
            
            # 检查URL是否可能仍然包含水印（简单的启发式检查）
            if "aweme.snssdk.com" in clean_video_url and "logo_name=" in clean_video_url:
                logger.warning(f"API返回的URL可能仍包含水印参数: {clean_video_url}")
                # 尝试移除水印参数
                try:
                    from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
                    parsed = urlparse(clean_video_url)
                    query_params = parse_qs(parsed.query)
                    # 移除可能的水印相关参数
                    watermark_params = ['logo_name', 'watermark', 'wm']
                    for param in watermark_params:
                        if param in query_params:
                            del query_params[param]
                    
                    # 重新构建URL
                    new_query = urlencode(query_params, doseq=True)
                    clean_video_url = urlunparse((
                        parsed.scheme, parsed.netloc, parsed.path,
                        parsed.params, new_query, parsed.fragment
                    ))
                    logger.info(f"已尝试移除水印参数，新URL: {clean_video_url}")
                except Exception as e:
                    logger.warning(f"移除水印参数失败: {e}")
                    # 继续使用原始URL，但标记为可能包含水印
            
            processing_time = time.time() - start_time
            
            # 构建成功结果
            return WatermarkResult(
                success=True,
                status=WatermarkResultStatus.SUCCESS,
                clean_video_url=clean_video_url,
                original_video_info=data,
                processing_time=processing_time
            )
            
        except Exception as e:
            processing_time = time.time() - start_time
            logger.error(f"去水印处理过程中发生错误: {e}", exc_info=True)
            return WatermarkResult(
                success=False,
                status=WatermarkResultStatus.FAILED,
                error_message=f"处理过程异常: {str(e)}",
                processing_time=processing_time
            )
    
    def _validate_video_url(self, url: str) -> bool:
        """
        验证视频URL的有效性
        
        Args:
            url: 待验证的URL
            
        Returns:
            是否有效
        """
        if not url or not isinstance(url, str):
            return False
        
        # 支持抖音分享文本或URL
        if "抖音" in url or "douyin" in url.lower():
            return True
        
        try:
            # 基本的URL格式验证
            parsed = urlparse(url)
            # 检查是否有有效的协议和域名
            if not parsed.scheme or not parsed.netloc:
                return False
            
            # 验证协议是否为http或https
            if parsed.scheme not in ['http', 'https']:
                return False
            
            # 验证域名格式（至少包含一个点）
            if '.' not in parsed.netloc:
                return False
            
            return True
        except Exception:
            return False
    
    def health_check(self) -> bool:
        """
        检查API服务健康状态
        
        Returns:
            服务是否可用
        """
        try:
            # 尝试访问基础URL
            response = self.session.get(
                self.api_base_url,
                timeout=10
            )
            return response.status_code == 200
        except Exception as e:
            logger.warning(f"API健康检查失败: {e}")
            return False
    
    def close(self):
        """关闭会话连接"""
        try:
            self.session.close()
            logger.info("第三方去水印API会话已关闭")
        except Exception as e:
            logger.warning(f"关闭会话时发生错误: {e}")


class LocalWatermarkRemover:
    """本地去水印逻辑（降级方案）"""
    
    def __init__(self):
        """初始化本地去水印处理器"""
        logger.info("初始化本地去水印处理器")
        self._chrome_available = self._check_chrome_availability()
        if not self._chrome_available:
            logger.warning("Chrome浏览器不可用，本地去水印功能将被禁用")
    
    def _check_chrome_availability(self) -> bool:
        """检查Chrome浏览器是否可用"""
        try:
            import shutil
            import subprocess
            
            # 检查常见的Chrome可执行文件
            chrome_paths = [
                'google-chrome', 'google-chrome-stable', 'chromium-browser', 
                'chromium', 'chrome', '/usr/bin/google-chrome',
                '/usr/bin/chromium-browser', '/usr/bin/chromium'
            ]
            
            for chrome_path in chrome_paths:
                if shutil.which(chrome_path):
                    logger.info(f"找到Chrome浏览器: {chrome_path}")
                    return True
            
            # 尝试使用which命令检查
            result = subprocess.run(['which', 'google-chrome'], capture_output=True, text=True)
            if result.returncode == 0 and result.stdout.strip():
                logger.info(f"找到Chrome浏览器: {result.stdout.strip()}")
                return True
                
            logger.error("未找到Chrome浏览器，本地去水印功能需要Chrome浏览器支持")
            return False
            
        except Exception as e:
            logger.error(f"检查Chrome可用性失败: {e}")
            return False
    
    def remove_watermark(self, video_url: str) -> WatermarkResult:
        """
        使用本地逻辑去水印 - 通过解析抖音分享链接获取无水印视频URL
        
        Args:
            video_url: 视频URL或分享文本
            
        Returns:
            去水印结果
        """
        start_time = time.time()
        
        # 首先检查Chrome浏览器是否可用
        if not self._chrome_available:
            processing_time = time.time() - start_time
            logger.error("Chrome浏览器不可用，无法执行本地去水印操作")
            return WatermarkResult(
                success=False,
                status=WatermarkResultStatus.FAILED,
                error_message="Chrome浏览器未安装，本地去水印功能不可用。请安装Chrome浏览器或使用第三方API服务。",
                processing_time=processing_time
            )
        
        try:
            # 导入抖音解析器模块
            from common.douyin_parser import parse_douyin_url
            
            logger.info(f"使用本地逻辑解析抖音视频: {video_url}")
            
            # 调用抖音解析器获取无水印视频URL
            ret = parse_douyin_url(video_url)
            
            # 添加详细的日志调试
            logger.info(f"parse_douyin_url返回值类型: {type(ret)}")
            logger.info(f"parse_douyin_url返回值: {repr(ret)}")
            
            if isinstance(ret, tuple) and len(ret) >= 2:
                success, result = ret[0], ret[1]
            elif isinstance(ret, str):
                success, result = True, ret
            else:
                success, result = False, f"本地解析器返回异常: {type(ret)} - {repr(ret)}"
            
            processing_time = time.time() - start_time
            
            if success:
                clean_video_url = result
                logger.info(f"本地解析成功，耗时: {processing_time:.2f}秒")
                
                return WatermarkResult(
                    success=True,
                    status=WatermarkResultStatus.SUCCESS,
                    clean_video_url=clean_video_url,
                    original_video_info={
                        "original_url": video_url,
                        "title": "抖音视频",
                        "description": "通过本地解析获取的无水印视频"
                    },
                    processing_time=processing_time
                )
            else:
                # result 包含错误信息
                logger.error(f"本地解析失败: {result}")
                return WatermarkResult(
                    success=False,
                    status=WatermarkResultStatus.FAILED,
                    error_message=f"本地解析失败: {result}",
                    processing_time=processing_time
                )
            
        except ImportError as e:
            processing_time = time.time() - start_time
            logger.error(f"导入抖音解析器失败: {e}")
            return WatermarkResult(
                success=False,
                status=WatermarkResultStatus.FAILED,
                error_message=f"本地处理模块不可用: {str(e)}",
                processing_time=processing_time
            )
        except Exception as e:
            processing_time = time.time() - start_time
            logger.error(f"本地去水印处理失败: {e}", exc_info=True)
            return WatermarkResult(
                success=False,
                status=WatermarkResultStatus.FAILED,
                error_message=f"本地处理失败: {str(e)}",
                processing_time=processing_time
            )


class WatermarkRemoverFacade:
    """去水印门面类，整合第三方API和本地逻辑"""
    
    def __init__(
        self,
        api_base_url: str = "https://mihoyonb.com",
        api_timeout: int = 30,
        enable_fallback: bool = True
    ):
        """
        初始化去水印门面
        
        Args:
            api_base_url: 第三方API基础URL
            api_timeout: API请求超时时间
            enable_fallback: 是否启用降级到本地逻辑
        """
        self.third_party_remover = ThirdPartyWatermarkRemover(api_base_url, api_timeout)
        self.local_remover = LocalWatermarkRemover()
        self.enable_fallback = enable_fallback
        
        logger.info(f"初始化去水印门面 - API: {api_base_url}, 降级: {enable_fallback}")
    
    def remove_watermark(self, video_url: str, prefer_local: bool = False) -> WatermarkResult:
        """
        执行去水印操作，支持降级策略
        
        Args:
            video_url: 视频URL
            prefer_local: 是否优先使用本地逻辑
            
        Returns:
            WatermarkResult对象
        """
        logger.info(f"开始去水印处理 - URL: {video_url}, 优先本地: {prefer_local}")
        
        # 如果优先使用本地逻辑，或者第三方API不可用
        if prefer_local or not self.enable_fallback:
            logger.info("使用本地去水印逻辑")
            return self.local_remover.remove_watermark(video_url)
        
        # 首先尝试第三方API
        logger.info("尝试使用第三方API去水印")
        result = self.third_party_remover.remove_watermark(video_url)
        
        # 如果第三方API失败且启用了降级，则使用本地逻辑
        if not result.success and self.enable_fallback:
            logger.warning("第三方API处理失败，降级到本地逻辑")
            local_result = self.local_remover.remove_watermark(video_url)
            
            # 在本地结果中标记这是降级处理
            if local_result.success:
                logger.info("降级到本地逻辑成功")
            else:
                logger.error("本地逻辑也处理失败")
            
            return local_result
        
        return result
    
    def health_check(self) -> Dict[str, bool]:
        """
        检查系统健康状态
        
        Returns:
            各组件健康状态
        """
        return {
            "third_party_api": self.third_party_remover.health_check(),
            "local_processor": True,  # 本地处理器总是可用的
            "fallback_enabled": self.enable_fallback
        }
    
    def close(self):
        """关闭资源"""
        try:
            self.third_party_remover.close()
            logger.info("去水印门面已关闭")
        except Exception as e:
            logger.warning(f"关闭去水印门面时发生错误: {e}")


# 全局实例
_watermark_remover_instance = None


def get_watermark_remover() -> WatermarkRemoverFacade:
    """获取全局去水印处理器实例"""
    global _watermark_remover_instance
    
    if _watermark_remover_instance is None:
        _watermark_remover_instance = WatermarkRemoverFacade()
    
    return _watermark_remover_instance


def cleanup_watermark_remover():
    """清理全局实例"""
    global _watermark_remover_instance
    
    if _watermark_remover_instance:
        try:
            _watermark_remover_instance.close()
            _watermark_remover_instance = None
            logger.info("全局去水印处理器已清理")
        except Exception as e:
            logger.warning(f"清理全局去水印处理器时发生错误: {e}")